﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HslCommunication.Profinet.Siemens;
using HslCommunication;
using System.Drawing.Imaging;
using 货物监控;
using 货物监控.Properties;
using System.Threading;
using System.Runtime.InteropServices.ComTypes;
using System.Text.RegularExpressions;
using System.Net.Sockets;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Diagnostics;
using PdfiumViewer;
using MQTTnet.Client;
using MQTTnet;
using System.Security.Cryptography.X509Certificates;
using Model;
using System.Diagnostics.Eventing.Reader;
using System.Resources;
using System.Net.NetworkInformation;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using DAL;
using System.Windows.Forms.VisualStyles;

namespace 货物监控
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;

        }
        #region 全局变量
        string plc1_ip = "10.95.24.38";         // PLC1 IP
        //string plc1_ip = "192.168.1.5";         // PLC1 IP
        string plc2_ip = "10.95.24.39";         // PLC2 IP
        StationRecord[] stationRecords = new StationRecord[8];
        Label[] suLabels,huLabels,wrapLabels,printLabels, stackLabels,suUpLabels,huUpLabels,partLabels;
        PictureBox[] ST_PICs;
        int printFlag = 0;                      // 打印机状态
        public string TempPath = "D:/Temp/JPG/";    //打印图片存储路径 
        TcpClient printClient = new TcpClient();// 打印机客户端
        private NetworkStream stream;           // 打印机数据流
        int print_status;                   // 打印机状态
        int waitRaiseTime = 300;                // ST60位置提升机等待时间
        int realTime = 0;                     // ST60位置等待提升机的实时时间
        IniConfig ini = new IniConfig("./config.ini"); // 配置文件
        public SiemensS7Net plc1 = new SiemensS7Net(SiemensPLCS.S1200); // PLC 1
        public SiemensS7Net plc2 = new SiemensS7Net(SiemensPLCS.S1200); // PLC 2
        //网络打印PDF路径
        string PrintPath = "\\\\vt1.vitesco.com\\SMT\\didd2241\\2_05_Public\\Auto Packing line pallet label\\Pallet label_Output files\\";
        string newPrintPath = "D:\\Temp\\PDF\\";
        string newPrintFile = "";
        SQL_Func sql_func = new SQL_Func();
        string ini_text = "待更新";
        string ini_bool = "0";
        string noChange = "no";
        private static readonly Mutex LogMutex = new Mutex(); // 在类的成员变量中声明互斥锁
        bool track_flag = false;
        int track_intflag = 0;
        public string AGVString = File.ReadAllText("AGV.txt").Trim();
        public static string pushString = File.ReadAllText("SAP.txt").Trim();
        int agv_position;
        #endregion


        #region PLC点位
        string st10_request = "DB200.DBX218.0";     // 【读取/写入】【Bool】ST10请求
        string st10_barCode = "DB200.DBB0";         // 【读取】【string】ST10条码
        string st10_haveSuNum = "DB200.DBX210";     // 【写入】【Int】判断SU号的
        string st10_noSuStr = "DB200.DBX52.0";      // 【写入】【string】写入异常字符串
        string st20_request = "DB200.DBX438.0";     // 【读取/写入】【Bool】ST20请求
        string st20_barCode = "DB200.DBB220";       // 【读取】【string】ST20条码
        string st20_wrap = "DB200.DBW430";          // 【写入】【Int】ST20写入是否缠膜，缠膜1，不缠膜2
        string st30_request = "DB200.DBX658.0";     // 【读取/写入】【Bool】ST30请求
        string st30_barCode = "DB200.DBB440";       // 【读取】【string】ST30条码
        string st40_request = "DB200.DBX878.0";     // 【读取/写入】【Bool】ST40请求
        string st40_isExist = "DB200.DBX878.5";     // 【写入】【int】ST40打印文件不存在
        string st40_printFile = "DB200.DBB764.0";  // ST40 【写入】【string】找不到打印文件，将文件名写到PLC
        string st40_barCode = "DB200.DBX660";       // 【读取】【string】ST40读码
        string st40_print = "DB200.DBW870";         // 【写入】【int】ST40打印 1.打印，2.不打印
        string st40_request2 = "DB200.DBX878.2";    // 【读取/写入】【Bool】ST40 请求2
        string st40_reprint = "DB200.DBX878.3";     // ST40 重新打印
        string st40_printReady = "DB200.DBX878.4";  // ST40 【写入】【bool】打印就绪，就是打印完成，打印完成写1，打印就绪写2
        string st40_printing = "DB200.DBX878.7";    // ST40 【写入】【bool】
        string st40_huCode = "DB200.DBB712";        // ST40 【读取】【string】贴完标读到的内容
        string st50_request = "DB200.DBX1098.0";    // ST50 【读取/写入】【Bool】请求
        string st50_barCode = "DB200.DBB880";       // ST50 【读取】【string】条码信息
        string st60_request = "DB200.DBX1318.0";    // ST60 【读取/写入】【Bool】请求
        string st60_barCode = "DB200.DBB1100";      // ST60 【读取】【string】读码
        string st60_isStock = "DB200.DBX1318.4";    // ST60 【读取】【Bool】判断堆叠机上面是否有货  
        string st60_Stack = "DB200.DBW1310";        // ST60 【写入】【int】堆叠机上有货，堆叠1，不堆叠2
        string st60_request2 = "DB200.DBX1318.2";   // ST60 请求2  True堆叠完成，False堆叠未完成
        string st70_request = "DB200.DBX1538.0";    // ST70 请求
        string st70_Push = "DB200.DBW1530";         // ST70 侧推气缸
        string st70_leave = "DB200.DBX1538.2";   // 【读取】ST70 请求拉走
        string st70_leaved = "DB200.DBX1760.2";       // 【读取】ST80 判断是否拉走
        // W整数，B字符串，X Bool值
        #endregion
        
        
        
        private void Form1_Load(object sender, EventArgs e)
        {
            if (!HslCommunication.Authorization.SetAuthorizationCode("f44b3795-d88e-4d48-b7c9-d38e3c48441e"))
            {
                MessageBox.Show("授权失败！当前程序只能使用8小时！");
            }
            suLabels = new Label[] { suLabelDown1, suLabelDown2, suLabelDown3, suLabelDown4, suLabelDown5, suLabelDown6, suLabelDown7, suLabelDown8 };
            huLabels = new Label[] { huLabelDown1, huLabelDown2, huLabelDown3, huLabelDown4, huLabelDown5, huLabelDown6, huLabelDown7, huLabelDown8 };
            wrapLabels = new Label[] { wrapLabel1, wrapLabel2, wrapLabel3, wrapLabel4, wrapLabel5, wrapLabel6, wrapLabel7, wrapLabel8 };
            
            printLabels = new Label[] { printLabel1, printLabel2, printLabel3, printLabel4, printLabel5, printLabel6, printLabel7, printLabel8 };
            stackLabels = new Label[] { stackLabel1, stackLabel2, stackLabel3, stackLabel4, stackLabel5, stackLabel6, stackLabel7, stackLabel8, };
            suUpLabels = new Label[] { suLabelUp1,suLabelUp2,suLabelUp3,suLabelUp4,suLabelUp5, suLabelUp6, suLabelUp7, suLabelUp8 };
            huUpLabels= new Label[] { huLabelUp1, huLabelUp2, huLabelUp3, huLabelUp4, huLabelUp5, huLabelUp6, huLabelUp7, huLabelUp8 };
            ST_PICs = new PictureBox[] { ST10_Pic, ST20_Pic, ST30_Pic, ST40_Pic, ST50_Pic, ST60_Pic, ST70_Pic, ST80_Pic };
            partLabels = new Label[] { partLabel1, partLabel2, partLabel3, partLabel4, partLabel5, partLabel6, partLabel7, partLabel8 };
            agv_position = Convert.ToInt32(ini.ReadKey("agv_position"));
            for (int i = 0;i< 8; i++)
            {
                stationRecords[i] = new StationRecord();
                loadRecord(stationRecords[i], ini.ReadKey($"ST{i+1}0"),i);
            }
            Task.Run(() => ConnectPrinter());   //打印机连接
            Task.Run(() => ConnPLC(plc1_ip));   // 连接PLC
            timer1.Start();
            // 连接AGV
            Task.Run(async () =>
            {
                TlsClientAGV("AmazonRootCA1.pem").Wait();
            });
            // 连接MQTT
            Task.Run(async () =>
            {
                TlsClient("whas007.wh.cn.int.Vitesco.com", 1883).Wait();
            });

            Thread th = new Thread(detStatus); // 状态监控
            th.IsBackground = true;
            th.Start();
            Task.Run(() => st10_func());  // 开启线程1 
        }
        // 计时器
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (printFlag > 0)
            {
                PrintHreat();  // 连接以后发送打印机心跳
            }
            plc1Heart();
            if (ReadBool("DB200.DBX878.6"))
            {
                WriteFalse("DB200.DBX878.6");
                string PngPath = "D:\\Temp\\2024-12-04\\2024_12_04_16_20_59_24120303_0001.png";
                NetForm.PrintImage(PngPath);
            }
        }
        // 关闭窗口提醒
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult result = MessageBox.Show("您确定关闭当前界面吗?", "温馨提示", MessageBoxButtons.YesNo);
            if (result == DialogResult.No)
            {
                e.Cancel = true;
            }
            else
            {
                if (Application.OpenForms.Count == 0)
                    Application.Exit();
            }
        }

        #region 函数
        // 进度跟进
        void detStatus()  // 通过状态符号显示在界面上
        {
            while (true)
            {
                for (int i = 0; i < 8; i++)
                {
                    if (stationRecords[i].Station_position == "A")
                    {
                        ST_PICs[i].Image = Resources.gray_circle;
                    }
                    else if (stationRecords[i].Station_position == "B")
                    {
                        ST_PICs[i].Image = Resources.green_circle;
                    }
                    else if (stationRecords[i].Station_position == "C")
                    {
                        ST_PICs[i].Image = Resources.blue_circle;
                    }
                    else if (stationRecords[i].Station_position == "D")
                    {
                        ST_PICs[i].Image = Resources.purple_circle;
                    }
                }
                agvLabel.Text = $"AGV送达点位：{agv_position}号位";
                Thread.Sleep(500);
            }
        }
        // 日志打印
        private void ShowMsg(string str)
        {
            try
            {
                txtLog.AppendText(DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss] ") + str + "\r\n");
                LogMutex.WaitOne(); // 获取互斥锁
                string fileName = DateTime.Now.ToString("yyyy_MM_dd_") + "log.txt";
                using (StreamWriter writer = File.AppendText(fileName))
                {
                    writer.WriteLine($"{DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss]")} - {str}");
                }
            }
            finally
            {
                LogMutex.ReleaseMutex(); // 释放互斥锁
            }
        }
        // 解析BarCode
        BarCode splicBar(string Bar)
        {
            Bar = Bar.Replace(",", "");

            string[] arr = Bar.Split('|');

            BarCode bc = new BarCode();
            if (arr.Length == 5)
            {
                bc.零件号 = arr[0].Trim();
                bc.工厂代码 = arr[1];
                bc.数量 = Convert.ToInt32(arr[2]);
                bc.SU号 = arr[3];
                bc.入库日期 = arr[4];
            }

            return bc;
        }
        #endregion

        #region 按钮

        private void button2_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 8; i++)
            {
                loadRecord(stationRecords[i], ini.ReadKey($"ST{i + 1}0"), i);
            }
        }
        private void MQTT_PIC_Click(object sender, EventArgs e)
        {
           
        }

        private void ST_Pic_Click(object sender, EventArgs e)
        {
            PictureBox st_pic = sender as PictureBox;
            int index = Array.IndexOf(ST_PICs, st_pic);
            updateProgress(index, ini_text, ini_bool, ini_bool, ini_bool, ini_text, ini_text, "A", ini_text, ini_text, ini_bool);


        }

        private void proButton1_Click(object sender, EventArgs e)
        {
            Task.Run(() => st10_func());
        }
        private void proButton2_Click(object sender, EventArgs e)
        {
            Task.Run(() => st20_func());
        }
        private void proButton3_Click(object sender, EventArgs e)
        {
            Task.Run(() => st30_func());
        }

        private void proButton4_Click(object sender, EventArgs e)
        {
            Task.Run(() => st40_func());
        }
        private void proButton5_Click(object sender, EventArgs e)
        {
            Task.Run(() => st50_func());
        }
        private void proButton6_Click(object sender, EventArgs e)
        {
            Task.Run(() => st60_func());
        }
        private void proButton7_Click(object sender, EventArgs e)
        {
            Task.Run(() => st70_func());
        }
        private void proButton8_Click(object sender, EventArgs e)
        {

        }

        private void waitTimeUpDown2_ValueChanged(object sender, EventArgs e)
        {
            // 获取 NumericUpDown 的整数值
            waitRaiseTime = (int)waitTimeUpDown.Value;
        }

        private void button5_Click(object sender, EventArgs e)
        {
            realTime -= 10;
        }

        private void button4_Click(object sender, EventArgs e)
        {
            realTime += 10;
        }

        #endregion

        #region PLC控制函数
        public bool ConnPLC(string ip)
        {
            // 连接  
            plc1.Rack = byte.Parse("0");
            plc1.Slot = byte.Parse("1");
            plc1.IpAddress = ip;
            plc1.Port = 102;
            try
            {
                OperateResult connect = plc1.ConnectServer();
                if (connect.IsSuccess)
                {
                    ShowMsg("PLC连接成功...");
                    PLC_PIC.Image = Resources.color_plc;
                    //WriteFalse("DB200.DBX218.0"); // ST10请求
                    //WriteFalse("DB200.DBX438.0"); // ST20请求
                    //WriteFalse("DB200.DBX658.0"); // ST30请求
                    //WriteFalse("DB200.DBX878.0"); // ST40请求
                    //WriteFalse("DB200.DBX878.3"); // ST40 重新打印
                    //WriteFalse("DB200.DBX878.2"); // ST40 请求2
                    //WriteFalse("DB200.DBX1098.0");// ST50 请求
                    //WriteFalse("DB200.DBX1318.0");// ST60 请求
                    //WriteFalse("DB200.DBX1318.2");// ST60 请求2
                    //WriteFalse("DB200.DBX1538.0");// ST70 请求
                    //WriteFalse("DB200.DBX1538.2");// ST70 请求拉走
                    //WriteFalse("DB200.DBX1760.2");// ST80 判断是否拉走
                    //  WriteInt("DB200.DBX210", 0);  // 判断SU号的
                    

                    return true;
                }
                else
                {
                    ShowMsg("PLC掉线...");
                    return false;
                }
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        // PLC写整数
        public void WriteInt(string key, short num)
        {
            plc1.Write(key, num);

            Task.Delay(200).Wait();

        }

        // PLC写False
        public void WriteFalse(string key)
        {

            plc1.Write(key, false);

            Task.Delay(200).Wait();

        }


        // PLC写Bool
        public bool WriteBool(string key, bool r)
        {
            OperateResult Result = plc1.Write(key, r);
            return Result.IsSuccess;
        }
        // 读取字符串
        public string ReadNumberString(string key, ushort length = 50)
        {
            OperateResult<string> result = plc1.ReadString(key, length);

            string str = result.Content.Substring(2, 48);

            return str;
        }

        // 写入字符串
        void writeString(string key,string text)
        {
            plc1.Write(key, text);
        }

        // PLC心跳
        public bool plc1Heart()
        {

            bool IsRead = ReadBool("DB200.DBX1540.0");

            bool br = WriteBool("DB200.DBX1540.0", !IsRead);

            return br;
        }

        public bool ReadBool(string key)
        {
            OperateResult<bool> result = plc1.ReadBool(key);

            bool br = result.Content;

            return br;
        }

        #endregion
        #region AGV相关
        // 启功MQTT
        void mqtt_start()
        {

            // MQTT小车
            Task.Run(async () =>
            {
                TlsClientAGV("AmazonRootCA1.pem").Wait();
            });
            
            // MQTT消息
            Task.Run(async () =>
            {
                TlsClient("whas007.wh.cn.int.Vitesco.com", 1883).Wait();
            });
        }
        // AGV小车发送
        public static IMqttClient AGVClient;
        // AGV回传
        public static IMqttClient mqttClient;
        // AGV连接
        public async Task TlsClientAGV(string caFile)
        {
            var mqttFactory = new MqttFactory();

            X509Certificate2 cacert = new X509Certificate2(File.ReadAllBytes(caFile));

            AGVClient = mqttFactory.CreateMqttClient();

            var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("hfms-mosquitto-whu.aws2144.vitesco.io", 8883)
                .WithCredentials("2933", "Hik@12342933")
                .WithTls(
                    new MqttClientOptionsBuilderTlsParameters()
                    {
                        UseTls = true,
                        SslProtocol = System.Security.Authentication.SslProtocols.Tls12,
                        CertificateValidationHandler = (certContext) =>
                        {
                            try
                            {
                                // 创建证书链
                                X509Chain chain = new X509Chain
                                {
                                    ChainPolicy =
                                        {
                                            RevocationMode = X509RevocationMode.NoCheck,
                                            RevocationFlag = X509RevocationFlag.ExcludeRoot,
                                            VerificationFlags = X509VerificationFlags.NoFlag,
                                            VerificationTime = DateTime.Now
                                        }
                                };

                                // 将自定义 CA 证书添加到额外存储中
                                chain.ChainPolicy.ExtraStore.Add(cacert);

                                // 将收到的证书转换为 X509Certificate2 类型
                                var x5092 = new X509Certificate2(certContext.Certificate);

                                // 验证证书链
                                bool isValid = chain.Build(x5092);

                                // 如果验证失败，打印详细信息
                                if (!isValid)
                                {
                                    foreach (var status in chain.ChainStatus)
                                    {
                                        Console.WriteLine($"证书链错误: {status.StatusInformation}");
                                    }
                                }

                                return isValid;
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine($"证书验证异常: {ex.Message}");
                                return false;
                            }
                        }

                    })
                .Build();

            AGVClient.ApplicationMessageReceivedAsync += e =>
            {
                return Task.CompletedTask;
            };

            using (var timeout = new CancellationTokenSource(5000))
            {
                await AGVClient.ConnectAsync(mqttClientOptions, timeout.Token);

                Console.WriteLine("The MQTT client is connected.");
            }

            var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()
           .WithTopicFilter(
               f =>
               {
                   f.WithTopic("naise/in/orderManager/create");
               })
           .Build();

            await AGVClient.SubscribeAsync(mqttSubscribeOptions, CancellationToken.None);

            ShowMsg("AGV小车连接成功");

        }
        // 给AGV发送消息
        public void SendAGV(string msg)
        {
            string topic = "naise/in/orderManager/create";
            MqttApplicationMessageBuilder mamb = new MqttApplicationMessageBuilder()
                  .WithTopic(topic)
                  .WithPayload(msg).WithRetainFlag(false);
            AGVClient.PublishAsync(mamb.Build());
            ShowMsg("发送给AGV:" + msg);
        }
        // 使用 MQTT 协议创建一个客户端，连接到指定的服务器，并订阅主题。
        public async Task TlsClient(string ip, int post)
        {
            var mqttFactory = new MqttFactory();// 创建一个 MQTT 工厂实例
            mqttClient = mqttFactory.CreateMqttClient();// 创建一个 MQTT 客户端实例
            // 配置 MQTT 客户端连接选项，设置目标服务器地址和端口号
            var mqttClientOptions = new MqttClientOptionsBuilder()
                .WithTcpServer(ip, post) // 设置 TCP 服务器的 IP 和端口
                .Build();
            // 设置 MQTT 客户端消息接收事件的处理逻辑
            mqttClient.ApplicationMessageReceivedAsync += e =>
            {
                // 获取主题和消息内容
                string topic = e.ApplicationMessage.Topic; // 消息的主题
                string payload = Encoding.UTF8.GetString(e.ApplicationMessage.Payload); // 消息的内容

                //// 在控制台打印接收到的消息
                //ShowMsg($"Received message: Topic={topic}, Payload={payload}");
                //// 调用日志方法显示消息内容
                //ShowMsg($"MQTT接收到消息: Topic={topic}, Payload={payload}");
                // 当前仅完成任务，无具体处理逻辑
                return Task.CompletedTask;
            };
            // 使用超时机制尝试连接到 MQTT 服务器
            using (var timeout = new CancellationTokenSource(5000)) // 设置超时时间为 5000 毫秒
            {
                await mqttClient.ConnectAsync(mqttClientOptions, timeout.Token); // 异步连接到服务器
                Console.WriteLine("The MQTT client is connected."); // 打印连接成功信息
            }
            // 配置订阅选项并订阅主题
            var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()
                .WithTopicFilter( // 设置订阅的主题
                    f =>
                    {
                        f.WithTopic("fromAgv"); // 订阅主题为 "fromAgv"
                    })
                .Build();
            // 异步订阅主题
            await mqttClient.SubscribeAsync(mqttSubscribeOptions, CancellationToken.None);

            // 显示连接成功消息
            ShowMsg("MQTT连接成功");
        }
        /// <summary>
        /// 发送 MQTT 消息
        /// </summary>
        /// <param name="msg">要发送的消息内容</param>
        public void SendMqtt(string msg)
        {
            // 定义 MQTT 消息的主题
            string topic = "fromAgv";

            // 创建 MQTT 消息
            var message = new MqttApplicationMessageBuilder()
                .WithTopic(topic)               // 设置主题
                .WithPayload(Encoding.UTF8.GetBytes(msg)) // 设置消息内容
                .WithRetainFlag(false)         // 消息不保留（Retain Flag 为 false）
                .Build();

            // 发布消息到 MQTT Broker
            mqttClient.PublishAsync(message).Wait();

            // 日志记录
            //ShowMsg("MQTT发布:" + msg);
        }



        // 呼叫AGV
        public void callAgv(int Site, string Na)
        {

            string json = "";
            try
            {
                if (Na.Equals("1"))
                {

                    Na = "2";
                }
                else
                {

                    Na = "1";
                }

                json = AGVString.Replace("{0}", Site.ToString()).Replace("{1}", Na);

                SendAGV(json);
                ShowMsg("发送给AGV:" + json);

                ShowMsg("AGV呼叫完成");

            }
            catch (Exception e)
            {
                ShowMsg("呼叫AGV:" + e.Message);
                TlsClientAGV("AmazonRootCA1.pem").Wait();
                callAgv(Site, Na);
            }

        }
        /// <summary>
        /// MQTT回写
        /// </summary>
        /// <param name="SU"></param>
        public void MQTTPush(string SU)
        {
            string json = "";
            try
            {
                PushLine sap = SQL_Func.getSAP70(SU);
                if (sap != null)
                {
                    if (sap.MSite >= 70)
                    {
                        string dt = DateTime.Now.ToString("yyyy-MM-dd HH:MM:ss fff");

                        json = pushString.Replace("{0}", sap.headerId).Replace("{1}", dt).Replace("{2}", sap.orderID);
                        SendMqtt(json);
                        SQL_Func.UpdateSAP70(SU);
                        ShowMsg("回传MQTT信息");
                    }
                }
            }
            catch (Exception e)
            {

                ShowMsg("MQTT回写:" + e.Message);
                ShowMsg("MQTT" + json);
            }
        }
        #endregion
        #region 打印机相关
        // 打印机心跳
        public void PrintHreat()
        {
            string key = "#OM>GP101\r\n";
            SendMsg(printClient, key);
        }

        // 连接打印机，并且进行监视
        private async Task ConnectPrinter()
        {
            string serverAddress = "10.95.16.62";
            int port = 9200;
            try
            {
                await printClient.ConnectAsync(serverAddress, port);
                print_PIC.Image = Resources.printer1;
                ShowMsg($"打印机连接成功");
                printFlag = 1;
                using (NetworkStream stream = printClient.GetStream())
                {
                    byte[] buffer = new byte[1024];
                    int bytesRead;
                    while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0)
                    {
                        // 将接收到的数据转换成字符串并显示
                        string receivedData = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                        print_status = GetPrinterStatus(receivedData);
                        
                        if (print_status == 0)  // 就绪
                        {
                            print_PIC.Image = Resources.printer1;
                        }
                        else if (print_status == 4) // 正在打印
                        {
                            print_PIC.Image = Resources.printer2;
                        }
                        else if(print_status == 12) // 异常
                        {
                            print_PIC.Image = Resources.printer_error;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ShowMsg($"Error with {serverAddress}:{port}: {ex.Message}");
            }
        }
        int print_num = 20;
        // 日志打印函数
        private async void SendMsg(TcpClient sock, string str)
        {
            var buffer = Encoding.UTF8.GetBytes(str);
            try
            {
                NetworkStream stream = sock.GetStream(); // 每次获取专属的 NetworkStream
                await stream.WriteAsync(buffer, 0, buffer.Length);
                Console.WriteLine($"Message sent: {str}");
            }
            catch (Exception ex)
            {
                ShowMsg($"打印机重连中");
                print_PIC.Image = Resources.no_printer;
                printClient = new TcpClient();
                if (print_num == 20)
                {
                    Task.Run(() => ConnectPrinter());   //打印机连接
                    print_num = 0;
                }
                print_num += 1;
            }
        }

        // 解析打印机返回的状态数据
        public static int GetPrinterStatus(string input)
        {
            try
            {
                // 提取 JSON 格式部分
                int startIndex = input.IndexOf("{");
                int endIndex = input.LastIndexOf("}");
                if (startIndex >= 0 && endIndex > startIndex)
                {
                    string jsonPart = input.Substring(startIndex, endIndex - startIndex + 1);

                    // 使用 Newtonsoft.Json 解析 JSON
                    JObject jsonObject = JObject.Parse(jsonPart);
                    if (jsonObject["printerStatus"] != null)
                    {
                        return jsonObject["printerStatus"].Value<int>();
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("解析失败: " + ex.Message);
            }

            // 默认返回值（若未成功解析）
            return -1;
        }
        #endregion
        #region PDF处理
        // 生成PDF图片
        public string getPath(string file_name)
        {

            string PngPath = TempPath + DateTime.Now.ToString("yyyy-MM-dd") + @"/";


            if (Directory.Exists(PngPath) == false)
            {
                Directory.CreateDirectory(PngPath);
            }

            PngPath += file_name + ".png";  // 需要修改，更新未原来地址

            return PngPath;
        }
        // 打印PDF
        void printPdf()
        {
            WriteInt(st40_print, 1);
            OpenFileDialog openFileDialog = new OpenFileDialog();
            //openFileDialog.InitialDirectory = "c:\\";//注意这里写路径时要用c:\\而不是c:\
            openFileDialog.Filter = "PDF文件|*.pdf";
            openFileDialog.RestoreDirectory = true;
            openFileDialog.FilterIndex = 1;

            DialogResult result = openFileDialog.ShowDialog();
            if (result == System.Windows.Forms.DialogResult.OK)
            {
                string PDFPath = openFileDialog.FileName;
                string fileName = Path.GetFileNameWithoutExtension(PDFPath);
                string PngPath = getPath(fileName);
                PdfToImage(PDFPath, PngPath);
                NetForm.PrintImage(PngPath);
                Task.Run(() =>
                {
                    Task.Delay(1000).Wait();

                    if (print_status == 4)
                    {
                        WriteBool(st40_printing, true);
                        while (true)
                        {
                            if (print_status == 0)
                            {
                                WriteBool(st40_printReady, true);
                                ShowMsg("打印完成，马上退出！");
                                break;
                            }
                            Task.Delay(500).Wait();
                        }

                        ShowMsg("等待就绪");
                    }


                });


            }
        }
        // PDF转图片
        public void PdfToImage(string pdfPath, string outputImagePath, int dpi = 300)
        {
            try
            {
                using (var document = PdfDocument.Load(pdfPath))
                {
                    // 获取第一页
                    var page = document.Render(0, 4000, 2800, dpi, dpi, PdfRenderFlags.Annotations);

                    // 将页面渲染为图片并保存
                    page.Save(outputImagePath, ImageFormat.Png);
                }
                ShowMsg("PDF 转换为图片成功！");
            }
            catch (Exception ex)
            {
                ShowMsg($"转换失败：{ex.Message}");
            }
        }
        void printFileExist(string file_name, string pdf_name)
        {
            Thread.Sleep(2000);
            WriteBool(st40_isExist, true);
            writeString(st40_printFile, $"no file:{pdf_name}.pdf");
            ShowMsg("打印文件不存在，请更新");
            while (true)
            {
                bool a = ReadBool(st40_reprint);
                if (ReadBool(st40_reprint))
                {
                    Thread.Sleep(200);
                    WriteFalse(st40_reprint);
                    if (!File.Exists(file_name))
                    {
                        printFileExist(file_name, pdf_name);

                    }
                    return;
                }
                Thread.Sleep(1000);
            }
        }
        // 文件移动
        void move_file(string old_path, string new_path)
        {
            try
            {
                // 确保目标文件夹存在
                string newfolder = Path.GetDirectoryName(new_path);
                if (!Directory.Exists(newfolder))
                {
                    Directory.CreateDirectory(newfolder);
                }

                // 移动文件（剪切）
                File.Move(old_path, new_path);
                Console.WriteLine("文件已成功剪切到目标文件夹！");
            }
            catch (IOException ex)
            {
                Console.WriteLine($"发生错误：{ex.Message}");
            }
            catch (UnauthorizedAccessException ex)
            {
                Console.WriteLine($"权限不足：{ex.Message}");
            }
        }
        #endregion
        #region 流程监控
        void st10_func()
        {
            ShowMsg("开始检测流程");
            while (true)
            {
                if (ReadBool(st10_request))
                {
                    Thread.Sleep(500);
                    string barCode_str = ReadNumberString(st10_barCode); // 读取条码
                    BarCode bc = splicBar(barCode_str); // 解析条码
                    XY_part part_data = sql_func.SelectPNumber(bc.零件号);//查询零件号是否需要缠膜
                    if(part_data == null)
                    {
                        ShowMsg($"未查询到零件号{bc.零件号}");
                        return;
                    }
                    updateProgress(0, bc.SU号, part_data.PWrapping, part_data.PPaying, part_data.PStacking, bc.零件号, ini_text, "B", ini_text, ini_text, part_data.PDirection);// 更新进度
                    WriteFalse(st10_request); // 写入False
                    ShowMsg($"ST10读取条码内容为：{barCode_str}");
                    int Count = sql_func.getSU(bc.SU号);
                    if (Count == 0)
                    {
                        WriteInt(st10_haveSuNum, 2); // 没有SU号
                        ShowMsg("没有查到相关项目号");// 
                        writeString(st10_noSuStr, "SuNumber not exist");
                        Task.Run(() => st10_func());// 重新开始
                        ShowMsg("没有查到相关项目号,重新开启St10函数");// 
                        return;
                    }
                    else
                    {
                        WriteInt(st10_haveSuNum, 1); // 有SU号，继续
                    }
                    bool st10_status = sql_func.Update10(bc.SU号, XY_task.WorkState.完成); // 更新ST10数据库
                    ShowMsg("ST10 完成");
                    Task.Run(() => st20_func()); // 启动流程2
                    return;
                }
            }

        }
        void st20_func()
        {
            ShowMsg("进入ST20流程");
            while (true)
            {

                if (ReadBool(st20_request))
                {
                    Task.Run(() => st10_func()); // 当货物到达ST20后创建新的线程
                    Thread.Sleep(500);
                    WriteFalse(st20_request);  // 关闭请求2
                    ShowMsg("ST20进入");
                    string barCode = ReadNumberString(st20_barCode); // 读码
                    BarCode bc = splicBar(barCode); // 读码
                    // 更新ST20流程，重置ST10流程
                    updateProgress(1, bc.SU号, stationRecords[0].is_warp, stationRecords[0].is_print, stationRecords[0].is_stack, stationRecords[0].Part_num, ini_text, "B", ini_text, ini_text, stationRecords[0].Push);
                    updateProgress(0, ini_text, ini_bool, ini_bool, ini_bool, ini_text, ini_text, "A", ini_text, ini_text, ini_bool);
                    // 更新数据库
                    bool bl = sql_func.Update20(bc.SU号, XY_task.WorkState.完成);
                    XY_part part_data = sql_func.SelectPNumber(bc.零件号);//查询零件号是否需要缠膜
                    WriteInt(st20_wrap, Convert.ToInt16(part_data.PWrapping)); //直接从当前进度读取是否需要缠膜
                    updateProgress(1, noChange, noChange, noChange, noChange, noChange, noChange, "C", ini_text, ini_text, noChange);// 更新ST20进度C
                    ShowMsg("缠膜完成");
                    Task.Run(() => st30_func()); // 启动ST30函数，结束ST20函数
                    return;
                }
            }
        }
        void st30_func()
        {
            ShowMsg("进入ST30流程");
            while (true)
            {
                if (ReadBool(st30_request))
                {
                    Thread.Sleep(500);
                    WriteFalse(st30_request); // 关闭信号
                    ShowMsg("ST30进入");
                    string barCode = ReadNumberString(st30_barCode); // 读码
                    BarCode bc = splicBar(barCode); // 读码
                    // 更新ST30流程，重置ST20流程
                    updateProgress(2, bc.SU号, stationRecords[1].is_warp, stationRecords[1].is_print, stationRecords[1].is_stack, stationRecords[1].Part_num, ini_text, "B", ini_text, ini_text, stationRecords[1].Push);
                    updateProgress(1, ini_text, ini_bool, ini_bool, ini_bool, ini_text, ini_text, "A", ini_text, ini_text, ini_bool);
                    XY_part Part20 = sql_func.SelectPNumber(bc.零件号);//查询零件号是否需要缠膜
                    ShowMsg("ST20 发送");
                    bool bl = sql_func.Update30(bc.SU号, XY_task.WorkState.完成); // 更新新数据库
                    ShowMsg("开始缠膜");  // 缠膜直接由ST20发送
                    Task.Run(() => st40_func()); // 启动ST40
                    return;
                }
            }
        }

        private void label3_Click(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {
            
        }

        void st40_func()
        {
            ShowMsg("进入ST40流程");
            while (true)
            {
                if (ReadBool(st40_request))
                {
                    Thread.Sleep(500);
                    WriteFalse(st40_request);

                    string barCode = ReadNumberString(st40_barCode); // 读码

                    BarCode bc = splicBar(barCode); // 读码
                    // 更新ST40流程，重置ST30流程
                    updateProgress(3, bc.SU号, stationRecords[2].is_warp, stationRecords[2].is_print, stationRecords[2].is_stack, stationRecords[2].Part_num, ini_text, "B", ini_text, ini_text, stationRecords[2].Push);
                    updateProgress(2, ini_text, ini_bool, ini_bool, ini_bool, ini_text, ini_text, "A", ini_text, ini_text, ini_bool);
                    bool bl = sql_func.Update40(bc.SU号, XY_task.WorkState.进入);// 更新数据库
                    XY_taskdetail Td = sql_func.SelectStorage_unit_number(bc.SU号);
                    // Td.PrintTask为dn号+item号的路径
                    string PDFPath = PrintPath + Td.PrintTask + ".pdf"; // pdf路径
                    string newPDFPath = newPrintPath + Td.PrintTask + ".pdf";
                    
                    ShowMsg($"打印文件为：{Td.PrintTask}.pdf");
                    printFileLabel.Text = $"打印文件：{Td.PrintTask}.pdf"; // 将打印的文件名称更新在界面上

                    if (!File.Exists(PDFPath))
                    {
                        printFileExist(PDFPath, Td.PrintTask);
                    }
                    move_file(PDFPath, newPDFPath); // 将旧文件移动到新文件夹
                    newPrintFile = newPDFPath; // 赋值给全局变量
                    XY_part part_data = sql_func.SelectPNumber(bc.零件号);//查询零件号是否需要缠膜
                    WriteInt(st40_print, Convert.ToInt16(part_data.PPaying)); // 打印
                    // 更新st40进度为C
                    updateProgress(3, noChange, noChange, noChange, noChange, noChange, noChange, "C", ini_text, ini_text, noChange);
                    string PngPath = getPath(Td.PrintTask);// 获取png路径

                    PdfToImage(newPDFPath, PngPath);// 转换图片并且保存到本地
                    NetForm.PrintImage(PngPath); //打印
                    while (true)
                    {
                        Thread.Sleep(1000);
                        if (print_status == 4)
                        {
                            WriteBool(st40_printing, true);
                            while (true)
                            {
                                if (print_status == 0)
                                {
                                    WriteBool(st40_printReady, true);
                                    ShowMsg("打印完成，马上退出！");
                                    printFileLabel.Text = "打印文件";
                                    break;
                                }
                                Task.Delay(500).Wait();
                            }
                            break;
                        }
                    }
                    ShowMsg("准备请求2");
                    while (true)
                    {
                        if (ReadBool(st40_request2))
                        {
                            //托盘标签码 HU号
                            string hu_num = ReadNumberString("DB200.DBB712").Trim().Replace("\0", "");
                            //保存HU
                            bool b = sql_func.UpdateHU(bc.SU号, hu_num);
                            updateProgress(3, noChange, noChange, noChange, noChange, noChange, hu_num.Substring(0, 10), "D", ini_text, ini_text, noChange);
                            sql_func.Update42(bc.SU号, hu_num, XY_task.WorkState.完成, Td.PrintTask);


                            // 更新数据库完成
                            Thread.Sleep(500);
                            WriteFalse(st40_request2);
                            ShowMsg("ST40结束");
                            break;
                        }
                    }
                    Task.Run(() => st50_func());
                    return;
                }
            }
        }
        // ST50函数
        void st50_func()
        {
            ShowMsg("开启ST50流程");
            while (true)
            {
                if (ReadBool(st50_request))
                {
                    ShowMsg("ST50 进入");

                    Thread.Sleep(500);
                    WriteFalse(st50_request); // 复位ST50

                    ShowMsg("更新ST50进度。");
                    // 更新ST50进度，重置ST40进度
                    updateProgress(4, stationRecords[3].SU_num_down, stationRecords[3].is_warp, stationRecords[3].is_print, stationRecords[3].is_stack, stationRecords[3].Part_num, stationRecords[3].HU_num_down, "B", ini_text, ini_text, stationRecords[3].Push);
                    updateProgress(3, ini_text, ini_bool, ini_bool, ini_bool, ini_text, ini_text, "A", ini_text, ini_text, ini_bool);
                    track_intflag++;
                    string barCode = ReadNumberString(st50_barCode); // 读码
                    BarCode bc = splicBar(barCode); // 读码
                    bool bl = sql_func.Update50(bc.SU号, XY_task.WorkState.完成);

                    Thread.Sleep(2000);   //等待2秒
                    ShowMsg("ST50结束");
                    Task.Run(() => st60_func());
                    return;
                }

            }
        }
        // ST60函数
        void st60_func()
        {
            ShowMsg("进入ST60流程");
            while (true)
            {
                if (ReadBool(st60_request))
                {
                    track_intflag++;// 提升机判断
                    WriteFalse(st60_request);
                    ShowMsg("进入ST60");
                    string barCode = ReadNumberString(st50_barCode); // 读码
                    BarCode bc = splicBar(barCode); // 读码
                    bool IsStacking = ReadBool(st60_isStock);// 判断升降机是否有货
                    sql_func.Update60(bc.SU号, XY_task.WorkState.进入);
                    if (IsStacking)
                    {
                        // 更新ST60，重置ST50
                        updateProgress(5, stationRecords[4].SU_num_down, stationRecords[4].is_warp, stationRecords[4].is_print, stationRecords[4].is_stack, stationRecords[4].Part_num, stationRecords[4].HU_num_down, "C", stationRecords[5].SU_num_down, stationRecords[5].HU_num_down, stationRecords[4].Push);
                        updateProgress(4, ini_text, ini_bool, ini_bool, ini_bool, ini_text, ini_text, "A", ini_text, ini_text, ini_bool);
                        track_intflag++;
                        ShowMsg("第二托线程结束");
                        return;  // 关闭线程
                    }
                    else
                    {
                        updateProgress(5, stationRecords[4].SU_num_down, stationRecords[4].is_warp, stationRecords[4].is_print, stationRecords[4].is_stack, stationRecords[4].Part_num, stationRecords[4].HU_num_down, "C", ini_text, ini_text, stationRecords[4].Push);
                        updateProgress(4, ini_text, ini_bool, ini_bool, ini_bool, ini_text, ini_text, "A", ini_text, ini_text, ini_bool);
                        sql_func.Update60(stationRecords[5].SU_num_down, XY_task.WorkState.进入);
                        XY_part part_data = sql_func.SelectPNumber(bc.零件号);//查询零件号是否需要缠膜

                        if (part_data.PPaying == "1") // 判断堆叠
                        {
                            // 开始堆叠
                            realTime = waitRaiseTime; // 获取等待时间
                            timeLabel.Text = $"开始等待。";
                            while (realTime > 0)
                            {
                                if (track_intflag == 3) // 等待ST50进入并且更新进度
                                {
                                    if (stationRecords[4].Part_num == stationRecords[5].Part_num)
                                    {
                                        WriteInt(st60_Stack, 1);//提升机开始提升
                                        ShowMsg("到位！开始提升");
                                        while (true)  // 等待第二托进入
                                        {
                                            if (track_intflag > 3) // 第二托进入，track_flag = false
                                            {
                                                timeLabel.Text = $"等待下次计时";
                                                Thread.Sleep(500);
                                                ShowMsg("第二托进入！准备堆叠");
                                                WriteInt(st60_Stack, 1);
                                                break;
                                            }
                                            Thread.Sleep(500);
                                        }
                                        while (true)  // 等待请求2
                                        {
                                            if (ReadBool(st60_request2)) // 堆叠完成的判断
                                            {
                                                Thread.Sleep(500);
                                                ShowMsg("堆叠完成");
                                                WriteFalse(st60_request2);
                                                track_intflag = 0;
                                                Task.Run(() => st70_func()); // 开启ST50流程
                                                return;
                                            }
                                            Thread.Sleep(500);
                                        }
                                    }
                                    else
                                    {
                                        realTime = 0;// 结束当前循环
                                    }
                                }
                                timeLabel.Text = $"提升等待时间：{realTime}";
                                Thread.Sleep(1000); // 等待
                                realTime -= 1;
                            }
                            timeLabel.Text = $"等待下次计时";
                            if (realTime <= 0)
                            {
                                WriteInt(st60_Stack, 2); // 不堆叠

                                while (true)  // 等待请求2
                                {
                                    if (ReadBool(st60_request2))
                                    {
                                        Thread.Sleep(500);
                                        WriteFalse(st60_request2);
                                        break;
                                    }
                                    Thread.Sleep(200);
                                }
                            }
                            Task.Run(() => st70_func());
                            return;
                        }
                        else
                        {
                            WriteInt(st60_Stack, 2); // 不堆叠

                            ShowMsg("不堆叠");
                            while (true)
                            {
                                if (ReadBool(st60_request2))
                                {
                                    Thread.Sleep(500);
                                    sql_func.Update60(bc.SU号, XY_task.WorkState.完成);
                                    WriteFalse(st60_request2);
                                    ShowMsg("ST60请求2复位");
                                    break;
                                }
                            }
                            track_intflag = 0;
                            Task.Run(() => st70_func());
                            return;
                        }

                    }
                }
            }
        }

        // ST70函数
        void st70_func()
        {
            ShowMsg("进入ST70流程");
            while (true)
            {
                if (ReadBool(st70_request))
                {
                    Thread.Sleep(500);
                    WriteFalse(st70_request);

                    ShowMsg("ST70结束等更新");
                    updateProgress(6, stationRecords[5].SU_num_down, stationRecords[5].is_warp, stationRecords[5].is_print, stationRecords[5].is_stack, stationRecords[5].Part_num, stationRecords[5].HU_num_down, "B", stationRecords[5].SU_num_up, stationRecords[5].HU_num_up, stationRecords[5].Push);
                    updateProgress(5, ini_text, ini_bool, ini_bool, ini_bool, ini_text, ini_text, "A", ini_text, ini_text, ini_bool);
                    if (stationRecords[6].HU_num_up != "待更新")
                    {
                        sql_func.Update70(stationRecords[6].SU_num_up, XY_task.WorkState.进行中);// 更新上托信息
                    }
                    sql_func.Update70(stationRecords[6].SU_num_down, XY_task.WorkState.进行中);// 更新下托信息
                    //MQTT回读
                    MQTTPush(stationRecords[6].SU_num_down);
                    WriteInt(st70_Push, Convert.ToInt16(stationRecords[6].Push));
                    while (true)
                    {
                        if (ReadBool(st70_leave))
                        {
                            Thread.Sleep(500);
                            XY_part part_data = sql_func.SelectPNumber(stationRecords[6].Part_num);
                            ShowMsg($"part_data.PDirection:{part_data.PDirection}");
                            callAgv(agv_position, part_data.PDirection);
                            agv_position += 1;
                            if (agv_position == 4)
                            {
                                agv_position = 1;
                            }
                            // 查询dn号
                            XY_taskdetail task_data = sql_func.SelectStorage_unit_number("1045019541");
                            string dn_num = task_data.dropdown_station_storage_bin;
                            if (stationRecords[6].SU_num_up.Length < 8)
                            {
                                update_agv_site(agv_position, dn_num, false); // 更新到AGV数据库

                            }
                            else
                            {
                                update_agv_site(agv_position, dn_num, true);
                            }
                            ini.WriteKey("agv_position", agv_position.ToString());
                            ShowMsg($"将会发送到:{agv_position}位置");
                            WriteFalse(st70_leave);
                            
                            break;
                        }
                    }
                    while (true)
                    {
                        if (ReadBool(st70_leaved))
                        {
                            Thread.Sleep(500);
                            WriteFalse(st70_leaved);
                            ShowMsg("货物已拉走");
                            if (stationRecords[6].HU_num_up != "待更新")
                            {
                                sql_func.Update80(stationRecords[6].SU_num_up);// 更新上托信息
                            }
                            sql_func.Update80(stationRecords[6].SU_num_down);// 更新下托信息
                            updateProgress(6, ini_text, ini_bool, ini_bool, ini_bool, ini_text, ini_text, "A", ini_text, ini_text, ini_bool);
                            break;
                        }
                    }
                    return;
                }
            }
        }

        #endregion
        #region 数据库相关函数
        void update_agv_site(int agv_pos, string dm_code,bool is_track)

        {
            string sql;
            int count;
            if (is_track) // 堆叠填写数据
            {
                sql = $"UPDATE XY_ParkingLot SET ID = {agv_pos}, [TO] = 'null', DN = '{dm_code}', LJ = '{stationRecords[6].Part_num}', HU = '{stationRecords[6].HU_num_up}', SU = '{stationRecords[6].SU_num_up}', OID = 0 WHERE TID = {agv_pos * 2 - 1};";
                count = DapperHelper<XY_ParkingLot>.Execute(sql);
            }
            else // 不堆叠数据填写空
            {
                sql = $"UPDATE XY_ParkingLot SET ID = {agv_pos}, [TO] = 'null', DN = 'null', LJ = 'null', HU = 'null', SU = 'null', OID = 0 WHERE TID = {agv_pos * 2 - 1};";
                count = DapperHelper<XY_ParkingLot>.Execute(sql);
                ShowMsg(sql);
            }

            sql = $"UPDATE XY_ParkingLot SET ID = {agv_pos}, [TO] = 'null', DN = '{dm_code}', LJ = '{stationRecords[6].Part_num}', HU = '{stationRecords[6].HU_num_down}', SU = '{stationRecords[6].SU_num_down}', OID = 1 WHERE TID = {agv_pos * 2};";
            count = DapperHelper<XY_ParkingLot>.Execute(sql);
        }
        
        
        #endregion
        #region 进度更新
        void loadRecord(StationRecord record,string load_str,int serial)
        {
            // 分割字符串
            string[] splitResult = load_str.Split(',');
            record.SU_num_down = splitResult[0];
            record.is_warp = splitResult[1];
            record.is_print = splitResult[2];
            record.is_stack = splitResult[3];
            record.Part_num = splitResult[4];
            record.HU_num_down = splitResult[5];
            record.Station_position = splitResult[6];
            record.SU_num_up = splitResult[7];
            record.HU_num_up = splitResult[8];
            record.Push= splitResult[9];
            // 更新到界面
            suLabels[serial].Text = stationRecords[serial].SU_num_down;
            huLabels[serial].Text = stationRecords[serial].HU_num_down;
            suUpLabels[serial].Text = stationRecords[serial].HU_num_up;
            huUpLabels[serial].Text = stationRecords[serial].HU_num_up;
            partLabels[serial].Text = stationRecords[serial].Part_num;
            if (stationRecords[serial].is_warp == "0")
            {
                wrapLabels[serial].Text = "待更新";
            }
            else if (stationRecords[serial].is_warp == "1")
            {
                wrapLabels[serial].Text = "缠膜";
            }
            else
            {
                wrapLabels[serial].Text = "不缠膜";
            }
            if (stationRecords[serial].is_print == "0")
            {
                printLabels[serial].Text = "待更新";
            }
            else if (stationRecords[serial].is_print == "1")
            {
                printLabels[serial].Text = "打印";
            }
            else
            {
                printLabels[serial].Text = "不打印";
            }

            if (stationRecords[serial].is_stack == "0")
            {
                stackLabels[serial].Text = "待更新";
            }
            else if (stationRecords[serial].is_stack == "1")
            {
                stackLabels[serial].Text = "堆叠";
            }
            else
            {
                stackLabels[serial].Text = "不堆叠";
            }

        }

        // 更新页面状态，并且保存到配置
        void updateProgress(int serial, string su_num_down, string warp, string print, string stack,string part_num, string hu_num_down, string station_position,string su_num_up, string hu_num_up,string push)
        {
            // 更新实例
            if (su_num_down != noChange) // 不更新
            {
                stationRecords[serial].SU_num_down = su_num_down;
            }
            if (warp != noChange)
            {
                stationRecords[serial].is_warp = warp;
            }
            if (print != noChange)
            {
                stationRecords[serial].is_print = print;
            }
            if (stack != noChange)
            {
                stationRecords[serial].is_stack = stack;
            }
            if (part_num != noChange)
            {
                stationRecords[serial].Part_num = part_num;
            }
            if (hu_num_down != noChange)
            {
                stationRecords[serial].HU_num_down = hu_num_down;
            }
            if (station_position != noChange)
            {
                stationRecords[serial].Station_position = station_position;
            }

            if (su_num_up != noChange) // 不修改SU
            {
                stationRecords[serial].SU_num_up = su_num_up;
            }
            if (hu_num_up != noChange) // 不修改下托的HU
            {
                stationRecords[serial].HU_num_up = hu_num_up;
            }
            if (push != noChange) // 不修改长短边参数 
            {
                stationRecords[serial].Push = push;
            }
            // 保存到配置
            ini.WriteKey($"ST{serial + 1}0", $"{stationRecords[serial].SU_num_down},{stationRecords[serial].is_warp},{stationRecords[serial].is_print},{stationRecords[serial].is_stack},{stationRecords[serial].Part_num},{stationRecords[serial].HU_num_down},{stationRecords[serial].Station_position},{stationRecords[serial].SU_num_up},{stationRecords[serial].HU_num_up},{stationRecords[serial].Push}");
            // 更新到界面
            suLabels[serial].Text = stationRecords[serial].SU_num_down;
            huLabels[serial].Text = stationRecords[serial].HU_num_down;
            // 更新到界面
            suUpLabels[serial].Text = stationRecords[serial].SU_num_up;
            huUpLabels[serial].Text = stationRecords[serial].HU_num_up;
            partLabels[serial].Text = stationRecords[serial].Part_num;

            if (stationRecords[serial].is_warp == "0")
            {
                wrapLabels[serial].Text = "待更新";
            }
            else if (stationRecords[serial].is_warp == "1")
            {
                wrapLabels[serial].Text = "缠膜";
            }
            else
            {
                wrapLabels[serial].Text = "不缠膜";
            }
            if (stationRecords[serial].is_print == "0")
            {
                printLabels[serial].Text = "待更新";
            }
            else if (stationRecords[serial].is_print == "1")
            {
                printLabels[serial].Text = "打印";
            }
            else
            {
                printLabels[serial].Text = "不打印";
            }

            if (stationRecords[serial].is_stack == "0")
            {
                stackLabels[serial].Text = "待更新";
            }
            else if (stationRecords[serial].is_stack == "1")
            {
                stackLabels[serial].Text = "堆叠";
            }
            else
            {
                stackLabels[serial].Text = "不堆叠";
            }
        }

        #endregion
    }
    // 条码信息
    public class BarCode
    {
        public string 零件号 { get; set; }
        public string 工厂代码 { get; set; }
        public int 数量 { get; set; }
        public string SU号 { get; set; }
        public string 入库日期 { get; set; }
    }



    public class StationRecord
    {
        public string SU_num_up {  get; set; }  // SU号
        public string HU_num_up { get; set; } // HU号
        public string is_warp { get; set; } // 是否缠膜
        public string is_print { get; set; } // 是否打印
        public string is_stack {  get; set; }// 是否堆叠
        public string Part_num {  get; set; }// 是否堆叠
        public string SU_num_down { get; set; }  // SU号
        public string HU_num_down { get; set; } // HU号
        public string Station_position { get; set; } // 当前工位进度
        public string Push { get; set; } // 是否侧推
    }


}
